import React, {Component, Fragment} from "react"
import PropTypes from "prop-types"
import './style.css'
import Fetch from "../../common/Fetch";
import Lodash from "lodash";

export default class GoCaptcha extends Component{
    static defaultProps = {
        value: PropTypes.bool.isRequired,
        width: '300px',
        height: '240px',
        calcPosType: PropTypes.oneOf(['dom', 'screen']),
        maxDot: 5,
        imageBase64: PropTypes.string,
        thumbBase64: PropTypes.string
    }

    constructor(props) {
        super(props);
        this.state = {
            imageBase64Code: '',
            thumbBase64Code: '',
            dots: [],
            captKey:'',
        }
    }

    componentDidMount() {
        this.handleRequestCaptCode()
    }

    handleRequestCaptCode = ()=>{
        Fetch('/serv/login/get_captcha_data',{},(res)=>{
            const {data = {}} = res;
            if ((data['code'] || 0) === 0) {
                if (Lodash.isEmpty(data)) {
                    return
                }
                console.log(data)
                this.setState({
                    imageBase64Code: data['image_base64'] || '',
                    thumbBase64Code:  data['thumb_base64'] || '',
                    captKey:  data['captcha_key'] || '',
                    dots:[],
                })
            } else {
                this.modal.alert(`获取人机验证数据失败`);
            }
        })
    }

    render() {
        const {
            width = '',
            height = '',
        } = this.props

        const {
            imageBase64Code,
            thumbBase64Code
        } = this.state

        const RenderDotItem = () => {
            const {dots = []} = this.state
            return dots.map((dot) => (<Fragment key={dot.index}>
                <div className="wg-cap-wrap__dot" style={{top: `${dot.y}px`, left: `${dot.x}px`}}>
                    <span>{dot.index}</span>
                </div>
            </Fragment>))
        }

        return(<Fragment>
            <div className="wg-cap-wrap">
                <div className="wg-cap-wrap__header">
                    <span>请在下图<em>依次</em>点击：</span>
                    {
                        thumbBase64Code && <img className="wg-cap-wrap__thumb" src={thumbBase64Code} alt=" "/>
                    }
                </div>
                <div className="wg-cap-wrap__body" style={{
                    width: width,
                    height: height
                }}>
                    {
                        imageBase64Code && <img className="wg-cap-wrap__picture"
                             src={imageBase64Code} alt=" "
                             onClick={this.handleClickPos}/>
                    }
                    <img className="wg-cap-wrap__loading"
                         src=""
                         alt="正在加载中..."/>
                        <RenderDotItem/>
                </div>
                <div className="wg-cap-wrap__footer">
                    <div className="wg-cap-wrap__ico">
                        <img onClick={this.handleCloseEvent}
                             src=""
                             alt="关闭"/>
                        <img onClick={this.handleRefreshEvent}
                             src=""
                             alt="刷新"/>
                    </div>
                    <div className="wg-cap-wrap__btn">
                        <button onClick={this.handleConfirmEvent}>确认</button>
                    </div>
                </div>
            </div>
        </Fragment>)
    }

    // // ===========
    componentWillReceiveProps(nextProps, nextContext) {
        console.log(nextProps)
        if (!nextProps.value){
            this.handleRequestCaptCode()
        }
    }
    // ================= Methods ================
    /**
     * @Description: 处理关闭事件
     */
    handleCloseEvent = () => {
        this.props.close && this.props.close()
        this.setState({
            dots: [],
            imageBase64Code: '',
            thumbBase64Code: ''
        });
    }

    /**
     * @Description: 处理刷新事件
     */
    handleRefreshEvent = () => {
        this.setState({
            dots: []
        });
        this.handleRequestCaptCode()
    }

    /**
     * @Description: 处理确认事件
     */
    handleConfirmEvent = () => {
        this.props.confirm && this.props.confirm(this.state.dots || [],this.state.captKey)
    }

    /**
     * @Description: 处理dot
     * @param ev
     */
    handleClickPos = (ev) => {
        const {dots = []} = this.state
        const {maxDot} = this.props

        if (dots.length >= maxDot) {
            return
        }
        const e = ev || window.event
        e.preventDefault()
        const dom = e.currentTarget

        const {domX, domY} = this.getDomXY(dom)
        // ===============================================
        // @notice 如 getDomXY 不准确可尝试使用 calcLocationLeft 或 calcLocationTop
        // const domX = this.calcLocationLeft(dom)
        // const domY = this.calcLocationTop(dom)
        // ===============================================

        let mouseX = (navigator.appName === 'Netscape') ? e.pageX : e.x + document.body.offsetTop
        let mouseY = (navigator.appName === 'Netscape') ? e.pageY : e.y + document.body.offsetTop
        if (this.props.calcPosType === 'screen') {
            mouseX = (navigator.appName === 'Netscape') ? e.clientX : e.x
            mouseY = (navigator.appName === 'Netscape') ? e.clientY : e.y
        }

        // 计算点击的相对位置
        const xPos = mouseX - domX
        const yPos = mouseY - domY

        // 转整形
        const xp = parseInt(xPos.toString())
        const yp = parseInt(yPos.toString())

        // 减去点的一半
        const newDots = [...dots, {
            x: xp - 11,
            y: yp - 11,
            index: dots.length + 1
        }]

        this.setState({
            dots: newDots
        });

        return false
    }
    /**
     * @Description: 找到元素的屏幕位置
     * @param el
     */
    calcLocationLeft = (el) => {
        let tmp = el.offsetLeft
        let val = el.offsetParent
        while (val != null) {
            tmp += val.offsetLeft
            val = val.offsetParent
        }
        return tmp
    }
    /**
     * @Description: 找到元素的屏幕位置
     * @param el
     */
    calcLocationTop = (el) => {
        let tmp = el.offsetTop
        let val = el.offsetParent
        while (val != null) {
            tmp += val.offsetTop
            val = val.offsetParent
        }
        return tmp
    }
    /**
     * @Description: 找到元素的屏幕位置
     * @param dom
     */
    getDomXY = (dom) => {
        let x = 0
        let y = 0
        if (dom.getBoundingClientRect) {
            let box = dom.getBoundingClientRect();
            let D = document.documentElement;
            x = box.left + Math.max(D.scrollLeft, document.body.scrollLeft) - D.clientLeft;
            y = box.top + Math.max(D.scrollTop, document.body.scrollTop) - D.clientTop
        }
        else{
            while (dom !== document.body) {
                x += dom.offsetLeft
                y += dom.offsetTop
                dom = dom.offsetParent
            }
        }
        return {
            domX: x,
            domY: y
        }
    }

}